﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace SoGame.Model
{
    /// <summary>
    /// 
    /// </summary>
    [Table("Players")]
    public partial class Player : INotifyPropertyChanged
    {
        private int id;
        private string firstName;
        private string name;
        private string email;
        private byte[] photo;
        private string searchString;
        private bool authorizePhotoUsage = true;

        /// <summary>
        /// Gets or sets the ID.
        /// </summary>
        /// <value>
        /// The ID.
        /// </value>
        [Key]
        [Column("ID")]
        public int ID
        {
            get
            {
                return this.id;
            }
            set
            {
                if (this.id != value)
                {
                    this.id = value;
                    this.OnPropertyChanged(() => ID);
                }
            }
        }

        /// <summary>
        /// Gets or sets the email.
        /// </summary>
        /// <value>
        /// The email.
        /// </value>
        [Required(ErrorMessage="L'email est obligatoire")]
        [StringLength(100)]
        [Column("Email")]
        [RegularExpression(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", 
            ErrorMessage="Le format de l'email est incorrect")]
        public string Email
        {
            get
            {
                return this.email;
            }
            set
            {
                if (this.email != value)
                {
                    this.email = value;
                    this.OnPropertyChanged(() => Email);
                }
            }
        }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        /// <value>
        /// The name.
        /// </value>
        [Required(ErrorMessage="Le nom est obligatoire")]
        [StringLength(50, MinimumLength=2, ErrorMessage="Veuillez saisir entre 2 et 50 caractères")]
        [Column("Name")]
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                if (this.name != value)
                {
                    this.name = value;
                    this.OnPropertyChanged(()=>Name);
                }
            }
        }

        /// <summary>
        /// Gets or sets the first name.
        /// </summary>
        /// <value>
        /// The first name.
        /// </value>
        [Required(ErrorMessage="Le prénom est obligatoire")]
        [StringLength(50, MinimumLength = 2, ErrorMessage = "Veuillez saisir entre 2 et 50 caractères")]
        [Column("FirstName")]
        public string  FirstName
        {
            get
            {
                return this.firstName;
            }
            set
            {
                if (this.firstName != value)
                {
                    this.firstName = value;
                    this.OnPropertyChanged(() => FirstName);
                }
            }
        }

        ///// <summary>
        ///// Gets the search string.
        ///// </summary>
        //[Column("SearchString")]
        //public string SearchString {
        //    get { return this.searchString; }
        //    set { this.searchString = value.RemoveDiacritics().ToLower(); }
        //}

        /// <summary>
        /// Gets or sets the photo.
        /// </summary>
        /// <value>
        /// The photo.
        /// </value>
        [Column("Photo")]
        public byte[] Photo {
            get { return this.photo; }
            set {
                if (this.photo != value) {
                    this.photo = value;
                    this.OnPropertyChanged(() => Photo);
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [authorize photo usage].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [authorize photo usage]; otherwise, <c>false</c>.
        /// </value>
        [Required]
        [Column("AuthorizePhotoUsage")]
        [DefaultValue(true)]
        public bool AuthorizePhotoUsage
        {
            get { return this.authorizePhotoUsage; }
            set {
                if (this.authorizePhotoUsage != value) {
                    this.authorizePhotoUsage = value;
                    OnPropertyChanged(() => AuthorizePhotoUsage);
                }
            }
        }

        #region INotifyPropertyChanged
        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action">The action.</param>
        protected void OnPropertyChanged<T>(Expression<Func<T>> action)
        {
            var propertyName = GetPropertyName(action);
            OnPropertyChanged(propertyName);
        }

        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        private void OnPropertyChanged(string propertyName)
        {
            //if ((new List<string> { "FirstName", "Name"}).Contains(propertyName)) {
            //    this.SearchString = string.Concat(this.FirstName, " ", this.Name);
            //}

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }

        /// <summary>
        /// Gets the name of the property.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private static string GetPropertyName<T>(Expression<Func<T>> action)
        {
            var expression = (MemberExpression)action.Body;
            var propertyName = expression.Member.Name;
            return propertyName;
        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        /// <summary>
        /// Gets or sets the game plays.
        /// </summary>
        /// <value>
        /// The game plays.
        /// </value>
        public virtual ICollection<GamePlay> GamePlays { get; set; }
    }
}
